package com.dx.mes.service.process.service;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import com.dx.common.table.ppt.*;
import com.dx.mes.common.dao.*;
import com.dx.mes.common.table.rtnBean.RouteObj;

import org.apache.commons.lang.StringUtils;
import org.hibernate.LockMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.dx.mes.common.table.rtnBean.SimpleRtnBeen;
import com.dx.mes.common.transcoder.util.AppContext;
import com.dx.mes.common.transcoder.util.GUIDGenerator;
import com.dx.mes.common.transcoder.util.JacksonUtil;
import com.dx.mes.common.transcoder.util.LogUtils;
import com.dx.mes.common.transcoder.util.Util;
import com.dx.mes.facade.process.service.IFppmoveoutService;
import com.dx.mes.facade.process.tx.Fppmoveout.FppmoveoutI;
import com.dx.mes.facade.process.tx.Fppmoveout.FppmoveoutIA;
import com.dx.mes.facade.process.tx.Fppmoveout.FppmoveoutO;
import com.dx.mes.facade.process.tx.Fppmoveout.FppmoveoutOA;

import static com.dx.mes.common.bean.def.GenericDef.*;


@Service("fppmoveoutService")
public class FppmoveoutService implements IFppmoveoutService {
    private LogUtils logUtils;

    @Autowired
    private IBisToolDao bisToolDao;
    @Autowired
    private IRetToolStDao retToolStDao;
    @Autowired
    private IRetBoxDao retBoxDao;
    @Autowired
    private IRetPrdInfoDao retPrdInfoDao;
    @Autowired
    private IBisPathDao bisPathDao;
    @Autowired
    private IBisPathiDao bisPathiDao;
    @Autowired
    private IBisDataDao bisDataDao;
    @Autowired
    private IRetWODao retWODao;
    @Autowired
    private IRetPrdOutDao retPrdOutDao;
    @Autowired
    private IRetFtRulDao retFtRulDao;
    @Autowired
    private IRetPrdAbnDao retPrdAbnDao;
    @Autowired
    private IBisPathSwhDao bisPathSwhDao;
    @Autowired
    private IBisOpeDao bisOpeDao;
    @Autowired
    private IBisToolGrDao bisToolGrDao;
    @Autowired
    private IRetPrdJgeDao retPrdJgeDao;
    @Autowired
    private IRetWoBomDao retWoBomDao;
    @Autowired
    private IRetToolMuDao retToolMuDao;
    @Autowired
    private IRetPrdMtdtDao retPrdMtdtDao;
    @Autowired
    private IRetLineWoDao retLineWoDao;


    public String subMainProc(String evt_no, String strInMsg) {
        AppContext.clear();
        AppContext.setCurrServiceName(FppmoveoutService.class.getSimpleName());
        AppContext.setCurrEventNumber(evt_no);
        logUtils = new LogUtils(FppmoveoutService.class);
        logUtils.info("[InTrx:" + strInMsg + "]");

        String strOutMsg = null;
        FppmoveoutI inTrx = new FppmoveoutI();
        FppmoveoutO outTrx = new FppmoveoutO();

        outTrx.setTrx_id(T_FPPMOVEOUT);
        outTrx.setType_id(TRX_OUT);
        outTrx.setRtn_code(String.valueOf(RETURN_CODE_SET_ERROR));
        try {
            inTrx = JacksonUtil.fromJson(strInMsg, FppmoveoutI.class);
            char action_flg = inTrx.getAction_flg().charAt(0);
            switch (action_flg) {
	            case ACTION_FLG_QUERY:
	                queryByConditionFnc(inTrx, outTrx);
	                break;
                case 'O'://main process
                	moveOut(inTrx, outTrx);
                    break;
                case 'T'://rework process
                	moveOutForRework(inTrx, outTrx);
                    break;
                case 'R':
                    regForFqc(inTrx, outTrx);
                    break;
                case 'F':
                    moveOutForFqc(inTrx, outTrx);
                    break;
                default:
                    outTrx = errActionFnc();
            }
            if (RETURN_CODE_OK.equals(outTrx.getRtn_code())) {
                retPrdInfoDao.flush();
            } else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        } catch (Exception ex) {
            outTrx.setRtn_code(RETURN_CODE_UNKNOWN);
            outTrx.setRtn_mesg("程式执行异常");
            logUtils.error(Util.stackTraceToString(ex));
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        } finally {
            strOutMsg = JacksonUtil.toJSONStr(outTrx);
            logUtils.info("[OutTrx:" + strOutMsg + "]");
        }
        return strOutMsg;
    }

    /**
     * 查询move out WIP
     * @param inTrx
     * @param outTrx
     */
    private void queryByConditionFnc(FppmoveoutI inTrx, FppmoveoutO outTrx) {
        FppmoveoutIA iary = inTrx.getIary().get(0);
        String woIdFk = iary.getWo_id_fk();
        String opeIdFk = iary.getOpe_id_fk();

        String hql = "From Ret_prd_info where 1=1 and prd_stat='INPR'";
        if (woIdFk != null && !woIdFk.equals(_SPACE)) {
            hql = hql + " and wo_id_fk = '" + woIdFk + "'";
        }
        if (opeIdFk != null && !opeIdFk.equals(_SPACE)) {
            hql = hql + " and cr_ope_id_fk = '" + opeIdFk + "'";
        }
        List<Ret_prd_info> ret_prd_infos = retPrdInfoDao.find(hql);
        List<FppmoveoutOA> oary = new ArrayList<FppmoveoutOA>();
        for (Ret_prd_info ret_prd_info : ret_prd_infos) {
            FppmoveoutOA fppmoveoutOA = new FppmoveoutOA();
            fppmoveoutOA.setPrd_seq_id(ret_prd_info.getPrd_seq_id());
            fppmoveoutOA.setMdl_id_fk(ret_prd_info.getMdl_id_fk());
            fppmoveoutOA.setWo_id_fk(ret_prd_info.getWo_id_fk());
            fppmoveoutOA.setPrd_stat(ret_prd_info.getPrd_stat());
            fppmoveoutOA.setPrd_grade(ret_prd_info.getPrd_grade());
            fppmoveoutOA.setSo_id_fk(ret_prd_info.getSo_id_fk());
            fppmoveoutOA.setMdl_id_fk(ret_prd_info.getMdl_id_fk());
            fppmoveoutOA.setLot_id(ret_prd_info.getLot_id());
            fppmoveoutOA.setNx_ope_id_fk(ret_prd_info.getNx_ope_id_fk());
            fppmoveoutOA.setNx_tool_id_fk(ret_prd_info.getNx_tool_id_fk());
            oary.add(fppmoveoutOA);
        }
        outTrx.setOary(oary);
        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
        return;
    }
    
    private void moveOut(FppmoveoutI inTrx, FppmoveoutO outTrx) {
    	SimpleRtnBeen rtnBeen = new SimpleRtnBeen(_NORMAL);
    	if(inTrx.getIary().size() == 0){
            outTrx.setRtn_code(E_FPPMOVEOUT_INVALID_INPUT + "");
            outTrx.setRtn_mesg("出账信息不正确");
            return;
    	}
    	
    	FppmoveoutIA iary = inTrx.getIary().get(0);
    	Ret_prd_info ret_prd_info = retPrdInfoDao.getWithLock(iary.getPrd_seq_id(), LockMode.UPGRADE);
        if (ret_prd_info == null) {
            outTrx.setRtn_code(E_RET_PRD_INFO + E_READ_NOT_FOUND + "");
            outTrx.setRtn_mesg("屏体信息不存在");
            return;
        }
        
        //检查屏体信息
		rtnBeen = checkPrdInfo(iary, ret_prd_info);
		if (rtnBeen.getlRc() != _NORMAL) {
            outTrx.setRtn_code(rtnBeen.getlRc() + "");
            outTrx.setRtn_mesg(rtnBeen.getMsgBuf());
            return;
		}
		
		//检查是否扣账
		rtnBeen = checkMtrlInfo(inTrx.getEvt_usr(), ret_prd_info);
		if (rtnBeen.getlRc() != _NORMAL) {
            outTrx.setRtn_code(rtnBeen.getlRc() + "");
            outTrx.setRtn_mesg(rtnBeen.getMsgBuf());
            return;
		}
		
		//检查工艺路线是否HOLD
		Bis_pathiId bis_pathiId = new Bis_pathiId();
    	bis_pathiId.setPath_id(ret_prd_info.getCr_path_id_fk());
		bis_pathiId.setPath_ver(ret_prd_info.getCr_path_ver_fk());
        Bis_pathi bis_pathi = bisPathiDao.get(bis_pathiId);
        if(bis_pathi == null){
            outTrx.setRtn_code(E_BIS_PATHI + E_READ_NOT_FOUND + "");
            outTrx.setRtn_mesg("未找到屏体工艺路线信息" + bis_pathiId.toString());
            return;
        }else if(PROC_HOLD.equals(bis_pathi.getPath_stat())){
            outTrx.setRtn_code(E_FPPMOVEOUT_PATH_STATUS_INVALIED + "");
            outTrx.setRtn_mesg("屏体工艺路线" + bis_pathiId.toString() + "状态为[" + PROC_HOLD + "]");
            return;
        }else if(!PATH_TYPE_MAIN.equals(bis_pathi.getPath_cate())){
            outTrx.setRtn_code(E_FPPMOVEOUT_INVALID_PATH_CATE + "");
            outTrx.setRtn_mesg("屏体工艺路线" + bis_pathiId.toString() + "必须为主工艺路线[" + PATH_TYPE_MAIN + "]");
            return;
        }
        
        //出账
        rtnBeen = realMoveOutProc(inTrx, ret_prd_info);
		if (rtnBeen.getlRc() != _NORMAL) {
            outTrx.setRtn_code(rtnBeen.getlRc() + "");
            outTrx.setRtn_mesg(rtnBeen.getMsgBuf());
			return;
		}
        rtnBeen = checkFutureAction(ret_prd_info);
        if (rtnBeen.getlRc() != _NORMAL) {
            outTrx.setRtn_code(rtnBeen.getlRc() + "");
            outTrx.setRtn_mesg(rtnBeen.getMsgBuf());
            return;
        }
        rtnBeen = skipFunc(inTrx, ret_prd_info);
        if (rtnBeen.getlRc() != _NORMAL) {
            outTrx.setRtn_code(rtnBeen.getlRc() + "");
            outTrx.setRtn_mesg(rtnBeen.getMsgBuf());
            return;
        }
        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
        return;
    }

    /**
     * Real Move Out
     * @return
     */
	private SimpleRtnBeen realMoveOutProc(FppmoveoutI inTrx, Ret_prd_info ret_prd_info) {
		Timestamp current_timestamp = Util.getCurrentTimestamp();
		FppmoveoutIA iary = inTrx.getIary().get(0);
        String prd_judge = iary.getPrd_judge();
		
		//出账时清空pv信息
        ret_prd_info.setPv_ope_id_fk(_SPACE);
        ret_prd_info.setPv_ope_no_fk(_SPACE);
        ret_prd_info.setPv_ope_ver_fk(_SPACE);
        ret_prd_info.setPv_path_id_fk(_SPACE);
        ret_prd_info.setPv_path_ver_fk(_SPACE);
        ret_prd_info.setPv_tool_id_fk(_SPACE);
        ret_prd_info.setPv_toolg_id_fk(_SPACE);
        ret_prd_info.setPv_proc_id_fk(_SPACE);
        ret_prd_info.setPv_tool_run_mode(_SPACE);
        
		if(!Util.isSpaceCheck(iary.getPrd_grade())){
			ret_prd_info.setPrd_grade(iary.getPrd_grade());
		}
		if(!Util.isSpaceCheck(iary.getDefect_code())){
	        ret_prd_info.setRsn_code(iary.getDefect_code());
	        
            Ret_prd_jgeId ret_prd_jgeId = new Ret_prd_jgeId();
            ret_prd_jgeId.setPrd_seq_id_fk(ret_prd_info.getPrd_seq_id());
            ret_prd_jgeId.setEvt_seq_id_fk(GUIDGenerator.javaGUID());
            ret_prd_jgeId.setData_seq_id_fk(1);
            Ret_prd_jge ret_prd_jge = new Ret_prd_jge();
            ret_prd_jge.setId(ret_prd_jgeId);
            ret_prd_jge.setPath_id_fk(ret_prd_info.getCr_path_id_fk());
            ret_prd_jge.setPath_ver_fk(ret_prd_info.getCr_path_ver_fk());
            ret_prd_jge.setOpe_no_fk(ret_prd_info.getCr_ope_no_fk());
            ret_prd_jge.setOpe_id_fk(ret_prd_info.getCr_ope_id_fk());
            ret_prd_jge.setOpe_ver_fk(ret_prd_info.getCr_ope_ver_fk());
            ret_prd_jge.setProc_id(ret_prd_info.getCr_proc_id_fk());
            ret_prd_jge.setPrd_grade_fk(ret_prd_info.getPrd_grade());
            ret_prd_jge.setJudge_cnt(1);
            ret_prd_jge.setJudge_tool_id_fk(ret_prd_info.getCr_tool_id_fk());
            ret_prd_jge.setJudge_usr(inTrx.getEvt_usr());
            ret_prd_jge.setJudge_timestamp(current_timestamp);
            ret_prd_jge.setDef_code(iary.getDefect_code());
            ret_prd_jge.setEvt_timestamp(current_timestamp);
            ret_prd_jge.setEvt_usr(inTrx.getEvt_usr());
            retPrdJgeDao.save(ret_prd_jge);
		}
        
		//获取重工工艺信息,更新下一制程站点为重工工艺的first ope no
		if(_NG.equals(iary.getPrd_judge()) && !Util.isSpaceCheck(iary.getRwk_route_id())){
			//获取重工工艺
			Bis_pathiId bis_pathiId = new Bis_pathiId();
			bis_pathiId.setPath_id(iary.getRwk_route_id());
			bis_pathiId.setPath_ver(iary.getRwk_route_ver());
			Bis_pathi bis_pathi = bisPathiDao.get(bis_pathiId);
			if(bis_pathi == null){
	        	return new SimpleRtnBeen(E_BIS_PATHI + E_READ_NOT_FOUND, "未找到工艺路线信息" + bis_pathiId.toString());
			}else if(PROC_HOLD.equals(bis_pathi.getPath_stat())){
	            return new SimpleRtnBeen(E_FPPMOVEOUT_PATH_STATUS_INVALIED, "屏体重工工艺路线" + bis_pathiId.toString() 
	            		+ "状态为[" + PROC_HOLD + "]");
			}
			
			//获取重工工艺First ope no信息
			Bis_pathId bis_pathId = new Bis_pathId();
			bis_pathId.setPath_id_fk(iary.getRwk_route_id());
			bis_pathId.setPath_ver_fk(iary.getRwk_route_ver());
			bis_pathId.setCr_ope_no(bis_pathi.getFirst_ope_no());
			Bis_path bis_path = bisPathDao.get(bis_pathId);
			if(bis_path == null){
				return new SimpleRtnBeen(E_BIS_PATH + E_READ_NOT_FOUND, "未找到工艺路线设定站点信息" + bis_pathId.toString());
			}
	        
			//获取站点信息
			Bis_opeId bis_opeId = new Bis_opeId();
			bis_opeId.setOpe_id(bis_path.getCr_ope_id_fk());
			bis_opeId.setOpe_ver(bis_path.getCr_ope_ver_fk());
			Bis_ope bis_ope = bisOpeDao.get(bis_opeId);
			if(bis_ope == null){
				return new SimpleRtnBeen(E_BIS_OPE + E_READ_NOT_FOUND, "未找到站点信息" + bis_opeId.toString());
			}
			
			//获取站点设置的SWH信息
			Bis_path_swhId bis_path_swhId = new Bis_path_swhId();
			bis_path_swhId.setFr_path_id_fk(ret_prd_info.getCr_path_id_fk());
			bis_path_swhId.setFr_path_ver_fk(ret_prd_info.getCr_path_ver_fk());
			bis_path_swhId.setFr_ope_no_fk(ret_prd_info.getCr_ope_no_fk());
			bis_path_swhId.setSwh_id(iary.getRwk_id());
			bis_path_swhId.setSwh_typ(iary.getRwk_typ());
			Bis_path_swh bis_path_swh = bisPathSwhDao.get(bis_path_swhId);
			if(bis_path_swh == null){
				return new SimpleRtnBeen(E_BIS_PATH_SWH + E_READ_NOT_FOUND, "未找到屏体站点分支工艺路线设定" + bis_path_swhId.toString());
			}
			
			//Set Ret_prd_info
            ret_prd_info.setSv_ope_no_fk(ret_prd_info.getNx_ope_no_fk());
            ret_prd_info.setSv_ope_id_fk(ret_prd_info.getNx_ope_id_fk());
            ret_prd_info.setSv_ope_ver_fk(ret_prd_info.getNx_ope_ver_fk());
            ret_prd_info.setSv_path_id_fk(ret_prd_info.getNx_path_id_fk());
            ret_prd_info.setSv_path_ver_fk(ret_prd_info.getNx_path_ver_fk());
            ret_prd_info.setSv_proc_id_fk(ret_prd_info.getNx_proc_id_fk());
            ret_prd_info.setSv_toolg_id_fk(ret_prd_info.getNx_toolg_id_fk());
            ret_prd_info.setSv_tool_run_mode(ret_prd_info.getNx_tool_run_mode());
            
            ret_prd_info.setNx_ope_no_fk(bis_path.getId().getCr_ope_no());
            ret_prd_info.setNx_ope_id_fk(bis_path.getCr_ope_id_fk());
            ret_prd_info.setNx_ope_ver_fk(bis_path.getCr_ope_ver_fk());
            ret_prd_info.setNx_path_id_fk(bis_path.getId().getPath_id_fk());
            ret_prd_info.setNx_path_ver_fk(bis_path.getId().getPath_ver_fk());
            ret_prd_info.setNx_proc_id_fk(bis_ope.getProc_id());
            ret_prd_info.setNx_toolg_id_fk(bis_ope.getToolg_id_fk());
            ret_prd_info.setNx_tool_run_mode(bis_ope.getTool_run_mode());
            
            //Set Ret_prd_out
            Ret_prd_outId ret_prd_outId = new Ret_prd_outId();
            ret_prd_outId.setPrd_seq_id_fk(ret_prd_info.getPrd_seq_id());
            ret_prd_outId.setEvt_seq_id_fk(GUIDGenerator.javaGUID());
            ret_prd_outId.setEvt_timestamp(current_timestamp);
            Ret_prd_out ret_prd_out = new Ret_prd_out();
            ret_prd_out.setId(ret_prd_outId);
            ret_prd_out.setUnq_seq_id(GUIDGenerator.javaGUID());
            ret_prd_out.setRul_act_code(RUL_ACT_REWORK_OUT);
            ret_prd_out.setFr_path_id_fk(ret_prd_info.getCr_path_id_fk());
            ret_prd_out.setFr_path_ver_fk(ret_prd_info.getCr_path_ver_fk());
            ret_prd_out.setFr_ope_no_fk(ret_prd_info.getCr_ope_no_fk());
            ret_prd_out.setSwh_id(iary.getRwk_id());
            ret_prd_out.setSwh_typ(iary.getRwk_typ());
            ret_prd_out.setTo_path_id_fk(bis_path.getId().getPath_id_fk());
            ret_prd_out.setTo_path_ver_fk(bis_path.getId().getPath_ver_fk());
            ret_prd_out.setTo_ope_no_fk(bis_path.getId().getCr_ope_no());
            ret_prd_out.setOut_path_id_fk(bis_path_swh.getOut_path_id_fk());
            ret_prd_out.setOut_path_ver_fk(bis_path_swh.getOut_path_ver_fk());
            ret_prd_out.setOut_ope_no_fk(bis_path_swh.getOut_ope_no_fk());
            ret_prd_out.setRsn_code(iary.getDefect_code());
            ret_prd_out.setOpe_msg(iary.getSht_ope_msg());
            ret_prd_out.setEvt_usr(inTrx.getEvt_usr());
            retPrdOutDao.save(ret_prd_out);
		}
		
		if(Util.isSpaceCheck(ret_prd_info.getNx_ope_no_fk())){
			ret_prd_info.setPrd_stat(PROC_COMPLETE);
		}else{
	        ret_prd_info.setPrd_stat(PROC_WAIT);
		}
        ret_prd_info.setSht_ope_msg(iary.getSht_ope_msg());
        ret_prd_info.setLogof_usr(inTrx.getEvt_usr());
        ret_prd_info.setPv_logof_timestamp(ret_prd_info.getLogof_timestamp());
        ret_prd_info.setLogof_timestamp(current_timestamp);
        ret_prd_info.setEvt_usr(inTrx.getEvt_usr());
        ret_prd_info.setEvt_cate(EVT_LGOF);
        ret_prd_info.setEvt_timestamp(current_timestamp);
        ret_prd_info.setExt_9(prd_judge);
        retPrdInfoDao.update(ret_prd_info);
		return new SimpleRtnBeen(_NORMAL);
	}
	
    private void regForFqc(FppmoveoutI inTrx, FppmoveoutO outTrx) {
        Timestamp current_timestamp = Util.getCurrentTimestamp();
        FppmoveoutIA iary = inTrx.getIary().get(0);
        String evt_usr = inTrx.getEvt_usr();
        String prdSeqId = iary.getPrd_seq_id();
        String prd_judge = iary.getPrd_judge();
        String test_cate = iary.getTest_cate();
        String defect_code = iary.getDefect_code();

        Ret_prd_info ret_prd_info = retPrdInfoDao.get(prdSeqId);
        if (ret_prd_info == null) {
            outTrx.setRtn_code(E_FPPMOVEOUT_INPUT_ITEM_EMPT + "");
            outTrx.setRtn_mesg("玻璃信息不存在");
            return;
        }
        if (!ret_prd_info.getPrd_stat().equals("INPR")) {
            outTrx.setRtn_code(E_FPPMOVEOUT_SHT_STATUS_INVALIED + "");
            outTrx.setRtn_mesg("该玻璃不在制程当中");
            return;
        }
        //卡控抽检数量不能超出抽检设定数量
        String hqlCnt = "FROM Ret_prd_info where lot_id='" + ret_prd_info.getLot_id() +"'";
        if(test_cate.equals("T")){
            hqlCnt = hqlCnt + " and ext_1 is not null";
        }else if(test_cate.equals("D")){
            hqlCnt = hqlCnt + " and ext_3 is not null";
        }else if(test_cate.equals("W")){
            hqlCnt = hqlCnt + " and ext_5 is not null";
        }
        List<Ret_prd_info> prds = retPrdInfoDao.find(hqlCnt);
        int oftestCnt = Integer.valueOf(prds.size());//已经抽检的数量

        String hql = "FROM Bis_data where data_cate ='BTCT' and data_ext='" + ret_prd_info.getMdl_id_fk() + "'";
        List<Bis_data> bis_dataList = bisDataDao.find(hql);
        int testCnt =0;
        if (bis_dataList.size() > 0) {
            testCnt=Integer.valueOf(bis_dataList.get(0).getExt_1());//需要抽检的数量
        }
        if(oftestCnt==testCnt){
            outTrx.setRtn_code(E_FPPMOVEOUT_SHT_STATUS_INVALIED + "");
            outTrx.setRtn_mesg("批次["+ret_prd_info.getLot_id()+"]已经达到抽检设定数量，无须再抽检");
            return;
        }
        if (test_cate.equals("T")) {
            ret_prd_info.setExt_1(evt_usr);
            ret_prd_info.setExt_2(prd_judge);
            ret_prd_info.setEvt_cate("FQCT");//TP检测
            ret_prd_info.setPrd_grade(prd_judge);
        } else if (test_cate.equals("D")) {
            ret_prd_info.setExt_3(evt_usr);
            ret_prd_info.setExt_4(prd_judge);
            ret_prd_info.setEvt_cate("FQCD");//电讯检测
            ret_prd_info.setPrd_grade(prd_judge);
        } else if (test_cate.equals("W")) {
            ret_prd_info.setExt_5(evt_usr);
            ret_prd_info.setExt_6(prd_judge);
            ret_prd_info.setEvt_cate("FQCW");//外观检测
            ret_prd_info.setPrd_grade(prd_judge);
        }
        ret_prd_info.setEvt_timestamp(current_timestamp);
        ret_prd_info.setDef_code(defect_code);
        retPrdInfoDao.update(ret_prd_info);
        if(!Util.isSpaceCheck(defect_code)){
            Ret_prd_jgeId ret_prd_jgeId = new Ret_prd_jgeId();
            ret_prd_jgeId.setPrd_seq_id_fk(prdSeqId);
            ret_prd_jgeId.setEvt_seq_id_fk(GUIDGenerator.javaGUID());
            ret_prd_jgeId.setData_seq_id_fk(1);
            Ret_prd_jge ret_prd_jge = new Ret_prd_jge();
            ret_prd_jge.setId(ret_prd_jgeId);
            ret_prd_jge.setPath_id_fk(ret_prd_info.getCr_path_id_fk());
            ret_prd_jge.setPath_ver_fk(ret_prd_info.getCr_path_ver_fk());
            ret_prd_jge.setOpe_no_fk(ret_prd_info.getCr_ope_no_fk());
            ret_prd_jge.setOpe_id_fk(ret_prd_info.getCr_ope_id_fk());
            ret_prd_jge.setOpe_ver_fk(ret_prd_info.getCr_ope_ver_fk());
            ret_prd_jge.setProc_id(ret_prd_info.getCr_proc_id_fk());
            ret_prd_jge.setPrd_grade_fk(ret_prd_info.getPrd_grade());
            ret_prd_jge.setJudge_cnt(1);
            ret_prd_jge.setJudge_tool_id_fk(ret_prd_info.getCr_tool_id_fk());
            ret_prd_jge.setJudge_usr(evt_usr);
            ret_prd_jge.setJudge_timestamp(current_timestamp);
            ret_prd_jge.setDef_code(defect_code);
            ret_prd_jge.setEvt_timestamp(current_timestamp);
            ret_prd_jge.setEvt_usr(evt_usr);
            retPrdJgeDao.save(ret_prd_jge);
        }

        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
        return;
    }

    private void moveOutForFqc(FppmoveoutI inTrx, FppmoveoutO outTrx) {
        Timestamp current_timestamp = Util.getCurrentTimestamp();
        FppmoveoutIA iary = inTrx.getIary().get(0);
        String evt_usr = inTrx.getEvt_usr();
        String lotId = iary.getLot_id();
        String reOpe = iary.getReOpe();
        String reOpe_id = iary.getReOpe_id();

        String hqlLot = "FROM Ret_prd_info where lot_id = ?";
        List<Ret_prd_info> retPrdInfoList = retPrdInfoDao.list(hqlLot, lotId);
        for (Ret_prd_info ret_prd_info : retPrdInfoList) {
            if (!ret_prd_info.getPrd_stat().equals("INPR")) {
                outTrx.setRtn_code(E_FPPMOVEOUT_SHT_STATUS_INVALIED + "");
                outTrx.setRtn_mesg("该玻璃不在制程当中");
                return;
            }
			//CHECK PATH HOLD
			String woIdFk =ret_prd_info.getWo_id_fk();
			Ret_wo ret_wo = retWODao.get(woIdFk);
			if(null != ret_wo) {
				String path_id = ret_wo.getPath_id_fk();
				String hql1 = "From Bis_pathi where path_id = '" + path_id + "'";
				List<Bis_pathi> bis_pathis = bisPathiDao.find(hql1);
				if (bis_pathis.size() > 0) {
					String path_stat = bis_pathis.get(0).getPath_stat();
					if ("HOLD".equals(path_stat)) {
						outTrx.setRtn_code(E_FPPMOVEOUT_SHT_STATUS_INVALIED + "");
						outTrx.setRtn_mesg("该订单的工艺路线已经HOLD");
						return;
					}
				}
			}

			//出账时清空pv信息
            ret_prd_info.setPv_ope_id_fk(_SPACE);
            ret_prd_info.setPv_ope_no_fk(_SPACE);
            ret_prd_info.setPv_ope_ver_fk(_SPACE);
            ret_prd_info.setPv_path_id_fk(_SPACE);
            ret_prd_info.setPv_path_ver_fk(_SPACE);
            ret_prd_info.setPv_tool_id_fk(_SPACE);
            ret_prd_info.setPv_toolg_id_fk(_SPACE);
            ret_prd_info.setPv_proc_id_fk(_SPACE);
            ret_prd_info.setPv_tool_run_mode(_SPACE);
            ret_prd_info.setLot_id(_SPACE);//清空批次号
            ret_prd_info.setExt_14(_SPACE);
            ret_prd_info.setLogof_usr(evt_usr);
            ret_prd_info.setPv_logof_timestamp(ret_prd_info.getLogof_timestamp());
            ret_prd_info.setLogof_timestamp(current_timestamp);
            ret_prd_info.setPrd_stat(PROC_WAIT);
            ret_prd_info.setEvt_usr(evt_usr);
            ret_prd_info.setEvt_cate(EVT_LGOF);
            ret_prd_info.setEvt_timestamp(current_timestamp);

            if (reOpe != null && !reOpe.equals(_SPACE)) {

                Bis_pathId bis_pathId = new Bis_pathId();
                bis_pathId.setPath_ver_fk(ret_prd_info.getCr_path_ver_fk());
                bis_pathId.setPath_id_fk(ret_prd_info.getCr_path_id_fk());
                bis_pathId.setCr_ope_no(reOpe);
                Bis_path bis_path = bisPathDao.get(bis_pathId);
                if (null == bis_path) {
                    outTrx.setRtn_code(E_FPPMOVEOUT_SHT_STATUS_INVALIED + "");
                    outTrx.setRtn_mesg("重工途程此站点不存在");
                    return;
                }
                Bis_opeId bis_opeId = new Bis_opeId();
                bis_opeId.setOpe_id(reOpe_id);
                bis_opeId.setOpe_ver("00000");
                Bis_ope bis_ope = bisOpeDao.get(bis_opeId);
                if (null == bis_ope) {
                    outTrx.setRtn_code(E_FPPMOVEOUT_SHT_STATUS_INVALIED + "");
                    outTrx.setRtn_mesg("站点[" + reOpe_id + "]不存在");
                    return;
                }
                ret_prd_info.setNx_path_id_fk(ret_prd_info.getCr_path_id_fk());
                ret_prd_info.setNx_path_ver_fk(ret_prd_info.getCr_path_ver_fk());
                ret_prd_info.setNx_ope_no_fk(bis_path.getId().getCr_ope_no());
                ret_prd_info.setNx_ope_id_fk(bis_path.getCr_ope_id_fk());
                ret_prd_info.setNx_ope_ver_fk(bis_path.getCr_ope_ver_fk());
                ret_prd_info.setNx_proc_id_fk(bis_ope.getProc_id());
                ret_prd_info.setNx_toolg_id_fk(bis_ope.getToolg_id_fk());
                ret_prd_info.setNx_tool_run_mode(bis_ope.getTool_run_mode());
                ret_prd_info.setExt_8("L");
               /*String hqltool = "FROM Bis_tool_gr where 1=1 and toolg_id='" + bis_ope.getToolg_id_fk() + "'";
                List<Bis_tool_gr> bisToolGr = bisToolGrDao.find(hqltool);
                if (bisToolGr.size() != 0) {
                    ret_prd_info.setNx_tool_id_fk(bisToolGr.get(0).getId().getTool_id_fk());
                }*/
            }
            retPrdInfoDao.update(ret_prd_info);
        }
        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
        return;
    }

	private SimpleRtnBeen checkPrdInfo(FppmoveoutIA iary, Ret_prd_info ret_prd_info) {
		Bis_opeId bis_opeId = new Bis_opeId();
        if (!PROC_IN_PROCESS.equals(ret_prd_info.getPrd_stat())){
        	return new SimpleRtnBeen(E_FPPMOVEOUT_SHT_STATUS_INVALIED, "屏体状态不正确，必须为[" + PROC_IN_PROCESS + "]请确认");
        }else{
        	bis_opeId.setOpe_id(ret_prd_info.getCr_ope_id_fk());
        	bis_opeId.setOpe_ver(ret_prd_info.getCr_ope_ver_fk());
        }

        //获取站点信息
        Bis_ope bis_ope = bisOpeDao.get(bis_opeId);
        if(bis_ope == null){
        	return new SimpleRtnBeen(E_BIS_OPE + E_READ_NOT_FOUND, "未找到屏体站点信息" + bis_opeId.toString());
        }
        //获取设备群组信息,自动出账时跳过
        if(!Util.isSpaceCheck(iary.getTool_id_fk())){
            Bis_tool_grId bis_tool_grId = new Bis_tool_grId();
            bis_tool_grId.setTool_id_fk(iary.getTool_id_fk());
            bis_tool_grId.setToolg_id(bis_ope.getToolg_id_fk());
            Bis_tool_gr bis_tool_gr = bisToolGrDao.get(bis_tool_grId);
            if(bis_tool_gr == null){
                return new SimpleRtnBeen(E_BIS_TOOL_GR + E_READ_NOT_FOUND, "屏体站点" + bis_opeId.toString()
                        + "对应设备组[" + bis_ope.getToolg_id_fk()
                        + "]和入账设备[" + iary.getTool_id_fk() + "]无关联，无法出账，请确认");
            }

            //检查入账设备和出账设备是否相同
            if(!iary.getTool_id_fk().equals(ret_prd_info.getCr_tool_id_fk())){
                return new SimpleRtnBeen(E_FPPMOVEOUT_TOOL_UNMATCH, "屏体出账设备[" + iary.getTool_id_fk()
                        + "]与入账设备[" + ret_prd_info.getCr_tool_id_fk() + "]不匹配,请确认");
            }
        }
		//在制仓检查
        if (BANK_IN.equals(ret_prd_info.getBnk_flg())) {
            return new SimpleRtnBeen(E_FPPMOVEOUT_INVALID_BNK_FLG, "屏体当前在在制品仓，请先从在制品仓转出");
        }
        
		return new SimpleRtnBeen(_NORMAL);
	}
	
    /**
     * For Rework Move Out
     * @param inTrx
     * @param outTrx
     */
    private void moveOutForRework(FppmoveoutI inTrx, FppmoveoutO outTrx) {
    	SimpleRtnBeen rtnBeen = new SimpleRtnBeen(_NORMAL);
    	if(inTrx.getIary().size() == 0){
            outTrx.setRtn_code(E_FPPMOVEOUT_INVALID_INPUT + "");
            outTrx.setRtn_mesg("入账信息不正确");
            return;
    	}
    	
    	FppmoveoutIA iary = inTrx.getIary().get(0);
    	Ret_prd_info ret_prd_info = retPrdInfoDao.getWithLock(iary.getPrd_seq_id(), LockMode.UPGRADE);
        if (ret_prd_info == null) {
            outTrx.setRtn_code(E_RET_PRD_INFO + E_READ_NOT_FOUND + "");
            outTrx.setRtn_mesg("屏体信息不存在");
            return;
        }
        
        //检查屏体信息
		rtnBeen = checkPrdInfo(iary, ret_prd_info);
		if (rtnBeen.getlRc() != _NORMAL) {
            outTrx.setRtn_code(rtnBeen.getlRc() + "");
            outTrx.setRtn_mesg(rtnBeen.getMsgBuf());
            return;
		}
		
		//检查工艺路线是否HOLD
		Bis_pathiId bis_pathiId = new Bis_pathiId();
    	bis_pathiId.setPath_id(ret_prd_info.getCr_path_id_fk());
		bis_pathiId.setPath_ver(ret_prd_info.getCr_path_ver_fk());
        Bis_pathi bis_pathi = bisPathiDao.get(bis_pathiId);
        if(bis_pathi == null){
            outTrx.setRtn_code(E_BIS_PATHI + E_READ_NOT_FOUND + "");
            outTrx.setRtn_mesg("未找到屏体工艺路线信息" + bis_pathiId.toString());
            return;
        }else if(PROC_HOLD.equals(bis_pathi.getPath_stat())){
            outTrx.setRtn_code(E_FPPMOVEOUT_PATH_STATUS_INVALIED + "");
            outTrx.setRtn_mesg("屏体工艺路线" + bis_pathiId.toString() + "状态为[" + PROC_HOLD + "]");
            return;
        }else if(!PATH_TYPE_REWK.equals(bis_pathi.getPath_cate())){
            outTrx.setRtn_code(E_FPPMOVEOUT_INVALID_PATH_CATE + "");
            outTrx.setRtn_mesg("屏体工艺路线" + bis_pathiId.toString() + "必须为重工工艺路线[" + PATH_TYPE_REWK + "]");
            return;
        }
        
        //出账
        rtnBeen = realMoveOutProcForRework(inTrx, ret_prd_info);
		if (rtnBeen.getlRc() != _NORMAL) {
            outTrx.setRtn_code(rtnBeen.getlRc() + "");
            outTrx.setRtn_mesg(rtnBeen.getMsgBuf());
			return;
		}
		
        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
        return;
    }
    
    /**
     * Real Move Out
     * @return
     */
	private SimpleRtnBeen realMoveOutProcForRework(FppmoveoutI inTrx, Ret_prd_info ret_prd_info) {
		Timestamp current_timestamp = Util.getCurrentTimestamp();
		FppmoveoutIA iary = inTrx.getIary().get(0);
		
		//出账时清空pv信息
        ret_prd_info.setPv_ope_id_fk(_SPACE);
        ret_prd_info.setPv_ope_no_fk(_SPACE);
        ret_prd_info.setPv_ope_ver_fk(_SPACE);
        ret_prd_info.setPv_path_id_fk(_SPACE);
        ret_prd_info.setPv_path_ver_fk(_SPACE);
        ret_prd_info.setPv_tool_id_fk(_SPACE);
        ret_prd_info.setPv_toolg_id_fk(_SPACE);
        ret_prd_info.setPv_proc_id_fk(_SPACE);
        ret_prd_info.setPv_tool_run_mode(_SPACE);
        
		if(!Util.isSpaceCheck(iary.getPrd_grade())){
			ret_prd_info.setPrd_grade(iary.getPrd_grade());
		}
		if(!StringUtils.isEmpty(iary.getExt_9())){
		    ret_prd_info.setExt_9(iary.getExt_9());
        }
		if(!Util.isSpaceCheck(iary.getDefect_code())){
	        ret_prd_info.setRsn_code(iary.getDefect_code());
	        
            Ret_prd_jgeId ret_prd_jgeId = new Ret_prd_jgeId();
            ret_prd_jgeId.setPrd_seq_id_fk(ret_prd_info.getPrd_seq_id());
            ret_prd_jgeId.setEvt_seq_id_fk(GUIDGenerator.javaGUID());
            ret_prd_jgeId.setData_seq_id_fk(1);
            Ret_prd_jge ret_prd_jge = new Ret_prd_jge();
            ret_prd_jge.setId(ret_prd_jgeId);
            ret_prd_jge.setPath_id_fk(ret_prd_info.getCr_path_id_fk());
            ret_prd_jge.setPath_ver_fk(ret_prd_info.getCr_path_ver_fk());
            ret_prd_jge.setOpe_no_fk(ret_prd_info.getCr_ope_no_fk());
            ret_prd_jge.setOpe_id_fk(ret_prd_info.getCr_ope_id_fk());
            ret_prd_jge.setOpe_ver_fk(ret_prd_info.getCr_ope_ver_fk());
            ret_prd_jge.setProc_id(ret_prd_info.getCr_proc_id_fk());
            ret_prd_jge.setPrd_grade_fk(ret_prd_info.getPrd_grade());
            ret_prd_jge.setJudge_cnt(1);
            ret_prd_jge.setJudge_tool_id_fk(ret_prd_info.getCr_tool_id_fk());
            ret_prd_jge.setJudge_usr(inTrx.getEvt_usr());
            ret_prd_jge.setJudge_timestamp(current_timestamp);
            ret_prd_jge.setDef_code(iary.getDefect_code());
            ret_prd_jge.setEvt_timestamp(current_timestamp);
            ret_prd_jge.setEvt_usr(inTrx.getEvt_usr());
            retPrdJgeDao.save(ret_prd_jge);
		}
        
		if("N".equals(inTrx.getRepair_flg())){
			Bis_pathId bis_pathId = new Bis_pathId();
			bis_pathId.setPath_id_fk(iary.getNew_route_id());
			bis_pathId.setPath_ver_fk(iary.getNew_route_ver());
			bis_pathId.setCr_ope_no(iary.getNew_ope_no());
			Bis_path bis_path = bisPathDao.get(bis_pathId);
			if(bis_path == null){
				return new SimpleRtnBeen(E_BIS_PATH + E_READ_NOT_FOUND, "未找到工艺路线设定站点信息" + bis_pathId.toString());
			}
			
			//获取站点信息
			Bis_opeId bis_opeId = new Bis_opeId();
			bis_opeId.setOpe_id(bis_path.getCr_ope_id_fk());
			bis_opeId.setOpe_ver(bis_path.getCr_ope_ver_fk());
			Bis_ope bis_ope = bisOpeDao.get(bis_opeId);
			if(bis_ope == null){
				return new SimpleRtnBeen(E_BIS_OPE + E_READ_NOT_FOUND, "未找到站点信息" + bis_opeId.toString());
			}
			//Set Ret_prd_info
            ret_prd_info.setNx_ope_no_fk(bis_path.getId().getCr_ope_no());
            ret_prd_info.setNx_ope_id_fk(bis_path.getCr_ope_id_fk());
            ret_prd_info.setNx_ope_ver_fk(bis_path.getCr_ope_ver_fk());
            ret_prd_info.setNx_path_id_fk(bis_path.getId().getPath_id_fk());
            ret_prd_info.setNx_path_ver_fk(bis_path.getId().getPath_ver_fk());
            ret_prd_info.setNx_proc_id_fk(bis_ope.getProc_id());
            ret_prd_info.setNx_toolg_id_fk(bis_ope.getToolg_id_fk());
            ret_prd_info.setNx_tool_run_mode(bis_ope.getTool_run_mode());
		}else if("R".equals(inTrx.getRepair_flg())){
			//获取重工工艺路线信息
			Bis_pathiId bis_pathiId = new Bis_pathiId();
			bis_pathiId.setPath_id(iary.getRwk_route_id());
			bis_pathiId.setPath_ver(iary.getRwk_route_ver());
			Bis_pathi bis_pathi = bisPathiDao.get(bis_pathiId);
			if(bis_pathi == null){
	        	return new SimpleRtnBeen(E_BIS_PATHI + E_READ_NOT_FOUND, "未找到工艺路线信息" + bis_pathiId.toString());
			}else if(PROC_HOLD.equals(bis_pathi.getPath_stat())){
	            return new SimpleRtnBeen(E_FPPMOVEOUT_PATH_STATUS_INVALIED, "屏体重工工艺路线" + bis_pathiId.toString() 
	            		+ "状态为[" + PROC_HOLD + "]");
			}
			//获取重工工艺First ope no信息
			Bis_pathId bis_pathId = new Bis_pathId();
			bis_pathId.setPath_id_fk(iary.getRwk_route_id());
			bis_pathId.setPath_ver_fk(iary.getRwk_route_ver());
			bis_pathId.setCr_ope_no(bis_pathi.getFirst_ope_no());
			Bis_path bis_path = bisPathDao.get(bis_pathId);
			if(bis_path == null){
				return new SimpleRtnBeen(E_BIS_PATH + E_READ_NOT_FOUND, "未找到工艺路线设定站点信息" + bis_pathId.toString());
			}
			
			//获取站点信息
			Bis_opeId bis_opeId = new Bis_opeId();
			bis_opeId.setOpe_id(bis_path.getCr_ope_id_fk());
			bis_opeId.setOpe_ver(bis_path.getCr_ope_ver_fk());
			Bis_ope bis_ope = bisOpeDao.get(bis_opeId);
			if(bis_ope == null){
				return new SimpleRtnBeen(E_BIS_OPE + E_READ_NOT_FOUND, "未找到站点信息" + bis_opeId.toString());
			}
			
			//Set Ret_prd_info
            ret_prd_info.setNx_ope_no_fk(bis_path.getId().getCr_ope_no());
            ret_prd_info.setNx_ope_id_fk(bis_path.getCr_ope_id_fk());
            ret_prd_info.setNx_ope_ver_fk(bis_path.getCr_ope_ver_fk());
            ret_prd_info.setNx_path_id_fk(bis_path.getId().getPath_id_fk());
            ret_prd_info.setNx_path_ver_fk(bis_path.getId().getPath_ver_fk());
            ret_prd_info.setNx_proc_id_fk(bis_ope.getProc_id());
            ret_prd_info.setNx_toolg_id_fk(bis_ope.getToolg_id_fk());
            ret_prd_info.setNx_tool_run_mode(bis_ope.getTool_run_mode());
		}else if(Util.isSpaceCheck(ret_prd_info.getNx_ope_no_fk())){//重工路线最后一站，获取Ret_prd_out的out站点
			List<Ret_prd_out> ret_prd_out_list = retPrdOutDao.find("FROM Ret_prd_out WHERE prd_seq_id_fk = '" 
					+ ret_prd_info.getPrd_seq_id() + "' ORDER BY evt_timestamp asc");
			if(ret_prd_out_list.isEmpty()){
				return new SimpleRtnBeen(E_FPPMOVEOUT_NO_PRD_OUT_INFO, "未找到屏体" + ret_prd_info.getPrd_seq_id() + "转出信息[RET_PRD_OUT]");
			}else{
				Ret_prd_out ret_prd_out = ret_prd_out_list.get(0);
				Bis_pathId bis_pathId = new Bis_pathId();
				bis_pathId.setPath_id_fk(ret_prd_out.getOut_path_id_fk());
				bis_pathId.setPath_ver_fk(ret_prd_out.getOut_path_ver_fk());
				bis_pathId.setCr_ope_no(ret_prd_out.getOut_ope_no_fk());
				Bis_path bis_path = bisPathDao.get(bis_pathId);
				if(bis_path == null){
					return new SimpleRtnBeen(E_BIS_PATH + E_READ_NOT_FOUND, "未找到工艺路线设定站点信息" + bis_pathId.toString());
				}
				
				//获取站点信息
				Bis_opeId bis_opeId = new Bis_opeId();
				bis_opeId.setOpe_id(bis_path.getCr_ope_id_fk());
				bis_opeId.setOpe_ver(bis_path.getCr_ope_ver_fk());
				Bis_ope bis_ope = bisOpeDao.get(bis_opeId);
				if(bis_ope == null){
					return new SimpleRtnBeen(E_BIS_OPE + E_READ_NOT_FOUND, "未找到站点信息" + bis_opeId.toString());
				}
				//Set Ret_prd_info
	            ret_prd_info.setNx_ope_no_fk(bis_path.getId().getCr_ope_no());
	            ret_prd_info.setNx_ope_id_fk(bis_path.getCr_ope_id_fk());
	            ret_prd_info.setNx_ope_ver_fk(bis_path.getCr_ope_ver_fk());
	            ret_prd_info.setNx_path_id_fk(bis_path.getId().getPath_id_fk());
	            ret_prd_info.setNx_path_ver_fk(bis_path.getId().getPath_ver_fk());
	            ret_prd_info.setNx_proc_id_fk(bis_ope.getProc_id());
	            ret_prd_info.setNx_toolg_id_fk(bis_ope.getToolg_id_fk());
	            ret_prd_info.setNx_tool_run_mode(bis_ope.getTool_run_mode());
			}
            //删除Ret_prd_out
			retPrdOutDao.deleteAll(ret_prd_out_list);
		}
		ret_prd_info.setPrd_stat(PROC_WAIT);
        ret_prd_info.setSht_ope_msg(iary.getSht_ope_msg());
        ret_prd_info.setLogof_usr(inTrx.getEvt_usr());
        ret_prd_info.setPv_logof_timestamp(ret_prd_info.getLogof_timestamp());
        ret_prd_info.setLogof_timestamp(current_timestamp);
        ret_prd_info.setEvt_usr(inTrx.getEvt_usr());
        ret_prd_info.setEvt_cate(EVT_LGOF);
        ret_prd_info.setEvt_timestamp(current_timestamp);
        retPrdInfoDao.update(ret_prd_info);
		return new SimpleRtnBeen(_NORMAL);
	}
	
	private SimpleRtnBeen checkMtrlInfo(String evt_usr, Ret_prd_info ret_prd_info) {
		List<Ret_prd_mtdt> ret_prd_mtdts = new ArrayList<Ret_prd_mtdt>();
		Timestamp evt_timestamp = Util.getCurrentTimestamp();
		String evt_seq_id = GUIDGenerator.javaGUID();
		//获取MTCT设定
		String hql = "FROM Bis_data WHERE data_cate ='MTCT' AND ext_2='" + ret_prd_info.getCr_ope_id_fk() 
				+ "' AND ext_3='Y'";
        List<Bis_data> bis_dataList = bisDataDao.find(hql);
        if(bis_dataList.size()>0){
            for(Bis_data bis_data:bis_dataList){
                //检查设备、工单、物料类型是否mount物料
                String hqlMu = "FROM Ret_tool_mu WHERE tool_id_fk='" + ret_prd_info.getCr_tool_id_fk()
                        + "' AND mtrl_cate='" + bis_data.getData_ext()
                        + "' AND wo_id_fk='" + ret_prd_info.getWo_id_fk()
                        + "' AND mtrl_mode='" + _YES + "'";
                List<Ret_tool_mu> ret_tool_mus = retToolMuDao.find(hqlMu);
                if(ret_tool_mus.isEmpty()){
                    return new SimpleRtnBeen(E_RET_TOOL_MU + E_READ_NOT_FOUND,
                            "设备代码[" + ret_prd_info.getCr_tool_id_fk()
                                    + "],工单代码[" + ret_prd_info.getWo_id_fk()
                                    + "],物料种类[" + bis_data.getData_ext() + "]未装配并激活，请确认");
                }else if(ret_tool_mus.size() > 1){
                    return new SimpleRtnBeen(E_FPPMOVEOUT_INVALID_MTRL_MODE,
                            "设备代码[" + ret_prd_info.getCr_tool_id_fk()
                                    + "],工单代码[" + ret_prd_info.getWo_id_fk()
                                    + "]同一物料种类[" + bis_data.getData_ext() + "]已经激活多个物料代码，请确认");
                }

                Ret_tool_mu ret_tool_mu = ret_tool_mus.get(0);

                /******设定屏体绑定物料信息******/
                //检查是否绑定物料，如果有将Mtrl_mdl_stat置为N
                List<Ret_prd_mtdt> ret_prd_mtdt_olds = retPrdMtdtDao.find("FROM Ret_prd_mtdt WHERE prd_seq_id_fk='" + ret_prd_info.getPrd_seq_id()
                        + "' AND mtrl_cate='" + bis_data.getData_ext()
                        + "' AND mtrl_mdl_stat='Y'");
                if(!ret_prd_mtdt_olds.isEmpty()){
                    for(Ret_prd_mtdt ret_prd_mtdt:ret_prd_mtdt_olds){
                        ret_prd_mtdt.setMtrl_mdl_stat(_NO);
                    }
                    retPrdMtdtDao.saveOrUpdateAll(ret_prd_mtdt_olds);
                }
                //设定新的物料信息
                Ret_prd_mtdtId ret_prd_mtdtId = new Ret_prd_mtdtId();
                Ret_prd_mtdt ret_prd_mtdt = new Ret_prd_mtdt();
                ret_prd_mtdtId.setPrd_seq_id_fk(ret_prd_info.getPrd_seq_id());
                ret_prd_mtdtId.setEvt_seq_id_fk(evt_seq_id);
                ret_prd_mtdtId.setMtrl_cate(bis_data.getData_ext());
                ret_prd_mtdtId.setMtrl_prod_id_fk(ret_tool_mu.getId().getMtrl_prod_id_fk());
                ret_prd_mtdt.setId(ret_prd_mtdtId);
                ret_prd_mtdt.setMtrl_mdl_stat(_YES);
                ret_prd_mtdt.setWo_id_fk(ret_prd_info.getWo_id_fk());
                ret_prd_mtdt.setMtrl_batch(ret_tool_mu.getMtrl_lot_id());

                //获取标准用量
                Ret_wo_bomId ret_wo_bomId = new Ret_wo_bomId();
                ret_wo_bomId.setWo_id_fk(ret_prd_info.getWo_id_fk());
                ret_wo_bomId.setMtrl_cate(bis_data.getData_ext());
                ret_wo_bomId.setMtrl_prod_id_fk(ret_tool_mu.getId().getMtrl_prod_id_fk());
                Ret_wo_bom ret_wo_bom = retWoBomDao.get(ret_wo_bomId);
                if(ret_wo_bom == null){
                    return new SimpleRtnBeen(E_RET_WO_BOM + E_READ_NOT_FOUND,
                            "未找到工单代码[" + ret_prd_info.getWo_id_fk()
                                    + "]设定的物料类型[" + bis_data.getData_ext()
                                    + "]物料代码[" + ret_tool_mu.getId().getMtrl_prod_id_fk()
                                    + "]的信息");
                }
                ret_prd_mtdt.setMtrl_qty(ret_wo_bom.getMtrl_use_qty());
                ret_prd_mtdt.setEvt_usr(evt_usr);
                ret_prd_mtdt.setEvt_timestamp(evt_timestamp);
                ret_prd_mtdts.add(ret_prd_mtdt);

                //扣减设备物料信息
                if(ret_tool_mu.getMount_qty() - ret_tool_mu.getUse_qty() - ret_wo_bom.getMtrl_use_qty() < 0){//物料剩余数量小于标准用量
                    return new SimpleRtnBeen(E_FPPMOVEOUT_INVALID_MTRL_QTY,
                            "设备代码[" + ret_prd_info.getCr_tool_id_fk()
                                    + "],物料种类[" + bis_data.getData_ext()
                                    + "],物料代码[" + ret_tool_mu.getId().getMtrl_prod_id_fk()
                                    + "],工单代码[" + ret_prd_info.getWo_id_fk()
                                    + "],上料端口[" + ret_tool_mu.getId().getMount_loca()
                                    + "]的装配装配剩余使用数量[" + (ret_tool_mu.getMount_qty() - ret_tool_mu.getUse_qty())
                                    + "]小于物料标准使用数量[" + ret_wo_bom.getMtrl_use_qty() + "]");
                }

                ret_tool_mu.setUse_qty(ret_tool_mu.getUse_qty() + ret_wo_bom.getMtrl_use_qty());
                ret_tool_mu.setEvt_usr(evt_usr);
                ret_tool_mu.setEvt_timestamp(evt_timestamp);
                retToolMuDao.update(ret_tool_mu);
            }
            retPrdMtdtDao.saveOrUpdateAll(ret_prd_mtdts);
        }
		return new SimpleRtnBeen(_NORMAL);
	}
	
	/**检查预约操作
	 * 
	 * @param ret_prd_info
	 * @return
	 */
    private SimpleRtnBeen checkFutureAction( Ret_prd_info ret_prd_info) {
        //1检查预约保留
        Timestamp evt_timestamp = Util.getCurrentTimestamp();
	    String hql = "From Ret_ft_rule where prd_seq_id_fk = '"+ret_prd_info.getPrd_seq_id()+"' and path_id_fk = '"+ret_prd_info.getCr_path_id_fk()+"'" +
                "and path_ver_fk = '"+ret_prd_info.getCr_path_ver_fk()+"' and rul_act_code ='FTHL' and valid_flg ='Y'";
        List<Ret_ft_rule> ret_ft_rules = retFtRulDao.find(hql);
        for(Ret_ft_rule ret_ft_rule :ret_ft_rules){
            if(_HA.equals(ret_ft_rule.getAct_pos_flg())){//hold在站前
                if(ret_prd_info.getNx_ope_id_fk().equals(ret_ft_rule.getOpe_id_fk())){
                    ret_prd_info.setPv_prd_stat_fk(ret_prd_info.getPrd_stat());
                    ret_prd_info.setPrd_stat(PROC_HOLD);
                    ret_prd_info.setEvt_cate(ret_ft_rule.getRul_act_code());
                    ret_prd_info.setRsn_code(ret_ft_rule.getRsn_code());
                    ret_prd_info.setSht_ope_msg(ret_ft_rule.getOpe_note());
                    retPrdInfoDao.update(ret_prd_info);
                    //添加abn表信息
                    String evt_seq_id = GUIDGenerator.javaGUID();
                    Ret_prd_abn ret_prd_abn = new Ret_prd_abn();
                    Ret_prd_abnId ret_prd_abnId = new Ret_prd_abnId();
                    ret_prd_abnId.setPrd_seq_id_fk(ret_prd_info.getPrd_seq_id());
                    ret_prd_abnId.setEvt_seq_id_fk(evt_seq_id);
                    ret_prd_abn.setId(ret_prd_abnId);
                    ret_prd_abn.setWo_id_fk(ret_prd_info.getWo_id_fk());
                    ret_prd_abn.setNx_ope_id_fk(ret_prd_info.getNx_ope_id_fk());
                    ret_prd_abn.setBox_id_fk(ret_prd_info.getBox_id_fk());
                    ret_prd_abn.setAct_code(ABN_ACTION_HOLD);
                    ret_prd_abn.setPrd_stat(PROC_HOLD);
                    ret_prd_abn.setRsn_code(ret_ft_rule.getRsn_code());
                    ret_prd_abn.setPv_prd_stat(ret_prd_info.getPv_prd_stat_fk());
                    ret_prd_abn.setEvt_usr(ret_ft_rule.getEvt_usr());
                    ret_prd_abn.setEvt_timestamp(evt_timestamp);
                    retPrdAbnDao.save(ret_prd_abn);
                }
            }else{//hold在站后
                if(ret_prd_info.getCr_ope_id_fk().equals(ret_ft_rule.getOpe_id_fk())){
                    ret_prd_info.setPv_prd_stat_fk(ret_prd_info.getPrd_stat());
                    ret_prd_info.setPrd_stat(PROC_HOLD);
                    ret_prd_info.setEvt_cate(ret_ft_rule.getRul_act_code());
                    ret_prd_info.setRsn_code(ret_ft_rule.getRsn_code());
                    ret_prd_info.setSht_ope_msg(ret_ft_rule.getOpe_note());
                    retPrdInfoDao.update(ret_prd_info);
                    //添加abn表信息
                    String evt_seq_id = GUIDGenerator.javaGUID();
                    Ret_prd_abn ret_prd_abn = new Ret_prd_abn();
                    Ret_prd_abnId ret_prd_abnId = new Ret_prd_abnId();
                    ret_prd_abnId.setPrd_seq_id_fk(ret_prd_info.getPrd_seq_id());
                    ret_prd_abnId.setEvt_seq_id_fk(evt_seq_id);
                    ret_prd_abn.setId(ret_prd_abnId);
                    ret_prd_abn.setWo_id_fk(ret_prd_info.getWo_id_fk());
                    ret_prd_abn.setNx_ope_id_fk(ret_prd_info.getNx_ope_id_fk());
                    ret_prd_abn.setBox_id_fk(ret_prd_info.getBox_id_fk());
                    ret_prd_abn.setAct_code(ABN_ACTION_HOLD);
                    ret_prd_abn.setPrd_stat(PROC_HOLD);
                    ret_prd_abn.setRsn_code(ret_ft_rule.getRsn_code());
                    ret_prd_abn.setPv_prd_stat(ret_prd_info.getPv_prd_stat_fk());
                    ret_prd_abn.setEvt_timestamp(evt_timestamp);
                    retPrdAbnDao.save(ret_prd_abn);
                }
            }
        }
        //2检查预约跳站
        //3检查预约重工
	    return new SimpleRtnBeen(_NORMAL);
    }
    private SimpleRtnBeen skipFunc( FppmoveoutI inTrx, Ret_prd_info ret_prd_info) {
        Timestamp evt_timestamp = Util.getCurrentTimestamp();
        String    evt_usr = inTrx.getEvt_usr();
        Bis_pathId bis_pathIdS = new Bis_pathId();
        bis_pathIdS.setPath_id_fk(ret_prd_info.getNx_path_id_fk());
        bis_pathIdS.setPath_ver_fk(ret_prd_info.getNx_path_ver_fk());
        bis_pathIdS.setCr_ope_no(ret_prd_info.getNx_ope_no_fk());
        Bis_path bis_pathS = bisPathDao.get(bis_pathIdS);
        if (null == bis_pathS) {
            return new SimpleRtnBeen(E_FPPMOVEIN_SHT_STATUS_INVALIED ,"途程站点信息不存在" );
        }
        if (!Util.isSpaceCheck(bis_pathS.getSkip_flg())) {
            if (bis_pathS.getSkip_flg().equals("1")) {
                Bis_opeId bis_opeId1 = new Bis_opeId();
                bis_opeId1.setOpe_id(ret_prd_info.getNx_ope_id_fk());
                bis_opeId1.setOpe_ver(ret_prd_info.getNx_ope_ver_fk());
                Bis_ope bis_ope1 = bisOpeDao.get(bis_opeId1);
                if (null == bis_ope1) {
                    return new SimpleRtnBeen(E_FPPMOVEIN_SHT_STATUS_INVALIED  ,
                            "站点[" + ret_prd_info.getNx_ope_id_fk() + "]不存在" );
                }
                String hqltool1 = "FROM Bis_tool_gr where 1=1 and toolg_id='" + bis_ope1.getToolg_id_fk() + "'";
                List<Bis_tool_gr> bisToolGr1 = bisToolGrDao.find(hqltool1);
                String woIdFk = ret_prd_info.getWo_id_fk();
                String linwosql = "FROM Ret_line_wo where 1=1";
                linwosql += " and wo_id_fk = '" + woIdFk + "'";
                linwosql += " and ope_id_fk = '" + ret_prd_info.getNx_ope_id_fk() + "'";
                linwosql += " and valid_flg = 'Y'";
                List<Ret_line_wo> retLineWoList = retLineWoDao.find(linwosql);
                if(retLineWoList != null && retLineWoList.size() > 0){
                    //所有设备组下的设备ID
                    List<String> toolIdList = new ArrayList<>();
                    if (bisToolGr1.size() != 0) {
                        for(int j = 0;j < bisToolGr1.size();j++){
                            toolIdList.add(bisToolGr1.get(j).getId().getTool_id_fk());
                        }
                    }

                    //对应线别下的设备(从设备组中筛选）
                    String lineIdFk = retLineWoList.get(0).getLine_id_fk();
                    String hql1 = "FROM Bis_tool where 1=1";
                    hql1 += " and bay_id = '" +lineIdFk+"'";
                    String str = "";
                    for (int i = 0; i < toolIdList.size() - 1; i++) {
                        str = str + "'" + toolIdList.get(i).toString().trim() + "',";
                    }
                    str = str + "'" + toolIdList.get(toolIdList.size() - 1).toString().trim() + "'";
                    if (toolIdList.size() > 0) {
                        hql1 = hql1 + " and tool_id  in(" + str + ")";
                    }

                    List<Bis_tool> bisToolList = bisToolDao.find(hql1);

                    if(bisToolList != null && bisToolList.size() > 0){
                        ret_prd_info.setCr_tool_id_fk(bisToolList.get(0).getTool_id());
                    }

                    //存储pv信息
                    ret_prd_info.setPv_ope_id_fk(ret_prd_info.getCr_ope_id_fk());
                    ret_prd_info.setPv_ope_no_fk(ret_prd_info.getCr_ope_no_fk());
                    ret_prd_info.setPv_ope_ver_fk(ret_prd_info.getCr_ope_ver_fk());
                    ret_prd_info.setPv_path_id_fk(ret_prd_info.getCr_path_id_fk());
                    ret_prd_info.setPv_path_ver_fk(ret_prd_info.getCr_path_ver_fk());
                    ret_prd_info.setPv_tool_id_fk(ret_prd_info.getCr_tool_id_fk());
                    ret_prd_info.setPv_toolg_id_fk(ret_prd_info.getCr_toolg_id_fk());
                    ret_prd_info.setPv_proc_id_fk(ret_prd_info.getCr_proc_id_fk());
                    ret_prd_info.setPv_tool_run_mode(ret_prd_info.getTool_port_id_fk());

                    //存储cr信息
                    ret_prd_info.setCr_ope_id_fk(ret_prd_info.getNx_ope_id_fk());
                    ret_prd_info.setCr_ope_no_fk(ret_prd_info.getNx_ope_no_fk());
                    ret_prd_info.setCr_ope_ver_fk(ret_prd_info.getNx_ope_ver_fk());
                    ret_prd_info.setCr_path_id_fk(ret_prd_info.getNx_path_id_fk());
                    ret_prd_info.setCr_path_ver_fk(ret_prd_info.getNx_path_ver_fk());
                    ret_prd_info.setCr_toolg_id_fk(ret_prd_info.getNx_toolg_id_fk());
                    ret_prd_info.setCr_proc_id_fk(ret_prd_info.getNx_proc_id_fk());
                    ret_prd_info.setCr_tool_run_mode(ret_prd_info.getNx_tool_run_mode());

                    //获取下一制程站点信息
                    RouteObj nxRouteObj = bisPathDao.getNxPath(ret_prd_info.getNx_path_id_fk(),
                            ret_prd_info.getNx_path_ver_fk(), ret_prd_info.getNx_ope_no_fk());
                    if (_NORMAL == nxRouteObj.getLRc()) {
                        logUtils.info("[login_normal:" + ret_prd_info.getPrd_seq_id() + "]");
                        Bis_path nx_bis_path1 = nxRouteObj.getPath();
                        Bis_ope nx_bis_ope1 = nxRouteObj.getOpe();
                        ret_prd_info.setNx_ope_no_fk(nx_bis_path1.getId().getCr_ope_no());
                        ret_prd_info.setNx_ope_id_fk(nx_bis_path1.getCr_ope_id_fk());
                        ret_prd_info.setNx_ope_ver_fk(nx_bis_path1.getCr_ope_ver_fk());
                        ret_prd_info.setNx_path_id_fk(nx_bis_path1.getId().getPath_id_fk());
                        ret_prd_info.setNx_path_ver_fk(nx_bis_path1.getId().getPath_ver_fk());
                        ret_prd_info.setNx_proc_id_fk(nx_bis_ope1.getProc_id());
                        ret_prd_info.setNx_toolg_id_fk(nx_bis_ope1.getToolg_id_fk());
                        ret_prd_info.setNx_tool_run_mode(nx_bis_ope1.getTool_run_mode());
                    } else if (PATH_IS_FINISH == nxRouteObj.getLRc()) {
                        logUtils.info("[login_finish:" + ret_prd_info.getPrd_seq_id() + "]");
                        ret_prd_info.setNx_toolg_id_fk(_SPACE);
                        ret_prd_info.setNx_ope_id_fk(_SPACE);
                        ret_prd_info.setNx_ope_no_fk(_SPACE);
                        ret_prd_info.setNx_ope_ver_fk(_SPACE);
                        ret_prd_info.setNx_path_id_fk(_SPACE);
                        ret_prd_info.setNx_path_ver_fk(_SPACE);
                        ret_prd_info.setNx_proc_id_fk(_SPACE);
                        ret_prd_info.setNx_tool_run_mode(_SPACE);
                    } else {
                        return new SimpleRtnBeen(E_BIS_OPE + E_READ_NOT_FOUND ,
                                "获取下一制程站点错误：" + nxRouteObj.getGszMsgBuf());
                    }
                    ret_prd_info.setLogon_usr(evt_usr);
                    ret_prd_info.setPv_logof_timestamp(ret_prd_info.getLogof_timestamp());
                    ret_prd_info.setLogon_timestamp(evt_timestamp);
                    ret_prd_info.setPrd_stat(PROC_IN_PROCESS);
                    ret_prd_info.setEvt_usr(evt_usr);
                    ret_prd_info.setEvt_cate(EVT_LGON);
                    ret_prd_info.setEvt_timestamp(evt_timestamp);
                    retPrdInfoDao.update(ret_prd_info);
                }else{
                    return new SimpleRtnBeen(E_BIS_OPE + E_READ_NOT_FOUND ,
                            "当前工单未绑定或激活线别与站点，无法自动入账！");
                }
            }else if (bis_pathS.getSkip_flg().equals("3")) {//跳站
                //获取下一制程站点信息
                RouteObj nxRouteObj = bisPathDao.getNxPath(ret_prd_info.getNx_path_id_fk(),
                        ret_prd_info.getNx_path_ver_fk(), ret_prd_info.getNx_ope_no_fk());
                if (_NORMAL == nxRouteObj.getLRc()) {
                    logUtils.info("[login_normal:" + ret_prd_info.getPrd_seq_id() + "]");
                    Bis_path nx_bis_path1 = nxRouteObj.getPath();
                    Bis_ope nx_bis_ope1 = nxRouteObj.getOpe();
                    ret_prd_info.setNx_ope_no_fk(nx_bis_path1.getId().getCr_ope_no());
                    ret_prd_info.setNx_ope_id_fk(nx_bis_path1.getCr_ope_id_fk());
                    ret_prd_info.setNx_ope_ver_fk(nx_bis_path1.getCr_ope_ver_fk());
                    ret_prd_info.setNx_path_id_fk(nx_bis_path1.getId().getPath_id_fk());
                    ret_prd_info.setNx_path_ver_fk(nx_bis_path1.getId().getPath_ver_fk());
                    ret_prd_info.setNx_proc_id_fk(nx_bis_ope1.getProc_id());
                    ret_prd_info.setNx_toolg_id_fk(nx_bis_ope1.getToolg_id_fk());
                    ret_prd_info.setNx_tool_run_mode(nx_bis_ope1.getTool_run_mode());
                } else if (PATH_IS_FINISH == nxRouteObj.getLRc()) {
                    logUtils.info("[login_finish:" + ret_prd_info.getPrd_seq_id() + "]");
                    ret_prd_info.setNx_toolg_id_fk(_SPACE);
                    ret_prd_info.setNx_ope_id_fk(_SPACE);
                    ret_prd_info.setNx_ope_no_fk(_SPACE);
                    ret_prd_info.setNx_ope_ver_fk(_SPACE);
                    ret_prd_info.setNx_path_id_fk(_SPACE);
                    ret_prd_info.setNx_path_ver_fk(_SPACE);
                    ret_prd_info.setNx_proc_id_fk(_SPACE);
                    ret_prd_info.setNx_tool_run_mode(_SPACE);
                }
                else {
                    return new SimpleRtnBeen(E_BIS_OPE + E_READ_NOT_FOUND ,
                            "获取下一制程站点错误：" + nxRouteObj.getGszMsgBuf());
                }
                ret_prd_info.setEvt_usr(evt_usr);
                ret_prd_info.setEvt_cate(EVT_ASKP_OPERATION );
                ret_prd_info.setEvt_timestamp(evt_timestamp);
                retPrdInfoDao.update(ret_prd_info);
                this.skipFunc(inTrx, ret_prd_info);//可能出现连续跳站的情况，所以递归循环
            }else{
                return new SimpleRtnBeen(_NORMAL);
            }
        }
        return new SimpleRtnBeen(_NORMAL);
    }
    public FppmoveoutO errActionFnc() {
        FppmoveoutO fppmoveinO = new FppmoveoutO();
        fppmoveinO.setTrx_id(T_FPPMOVEOUT);
        fppmoveinO.setType_id(TRX_OUT);
        fppmoveinO.setRtn_code(E_FPPMOVEOUT_INVALID_INPUT + "");
        fppmoveinO.setRtn_mesg("Invalid Action_flg");
        return fppmoveinO;
    }
}